%w(open-uri rubygems xmpp4r-simple).each { |f| require f }
require 'robot'

module Jabber
   def deliver(addr, mesg)
      log("sending #{mesg} to #{addr}")
      jabber.deliver(addr, mesg)
   end

   def jabber
     begin
       unless @jabber
         log("connecting....")
         @jabber = Jabber::Simple.new(@jabber_id, @jabber_pw, :chat, "Open for Business.")
         log("connected as #{@jabber_id}")
       end  
     rescue => e
       puts e.message
       print e.backtrace.join("\n")
       log("[#{Time.now}] Couldn't connect to Jabber (#{@jabber_id}, #{@jabber_pw}): #{e}.")
       sleep 60
       retry
     end
     @jabber
   end
end

module Twitter
   include Jabber

   def twitter(text)
     log("twittered #{text}")
     deliver('twitter@twitter.com', text)
   end

   def tell(person, text)
      if person =~ /@/
         deliver(person, text)
      else
         twitter("d #{person} #{text}")
      end
      true
   end
   
   def befriend_all_followers
      log('befriending all...')
      begin
         open( 'http://twitter.com/followers/befriend_all',
               :http_basic_authentication => [@twitter_email, @twitter_pw],
               "User-Agent" => @twitter_email );
         log('succeeded!')
      rescue
         log "can't connect to twitter to befriend_all!"
      end
   end   
end


class TwitterBot < Robot
   include Twitter
   
   def initialize(un, pw)
      @jabber_id = @twitter_email = un
      @jabber_pw = @twitter_pw = pw
      @available_friends = {}
   end

   def available_friends; @available_friends.values; end

   def scan_messages
      jabber.received_messages.each{ |m| process_message(m) }
   end

   #sender = mesg.elements['//screen_name'].text
   def process_message(mesg)
      log("recieved #{mesg}")
      sender = mesg.from.to_s.sub(/\/.+$/, '')
      return receive(:im, sender, mesg.body) unless sender =~ /^twitter@twitter/
      case mesg.body
      when /direct from (\w+)/
         sender = $1
         text = mesg.body.sub("direct from #{sender}: ", '').
                          sub("(reply? send: d #{sender} hi.)", '').strip
         return receive(:direct, sender, text)
      when /^(\w+):/
         sender = $1
         text.sub!(/^(\w+):/, '')
         return receive(:twiiter, sender, text)
      else
         raise "twitter is sending me something weird:  #{sender}::#{mesg.body}"
      end
   end

   def scan_friends
      jabber.presence_updates do |update|
         who, state, str = *update
         log "presence update:  #{who}, #{state}, #{str}"
         next if who =~ /twitter@twitter.com/
         if state and state != :unavailable
            f = Friends[who]
            @available_friends[who] = f
            f.seen!
         else
            @available_friends.delete(who)
         end
      end
   end
end
